﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Workshop2
{
    class Controller
    {
        // Kontruktorn
        public Controller(Repository repository, ViewAll v)
        {
            view = v;
            r = repository;
        }
        // Enums för menystatus
        enum MenuStatus
        {
            None,
            Exit,
            AddPerson,
            ViewPersons,
            ViewPersonsInfo,
            DeletePerson,
            ChangePerson,
            ViewOnePerson,
            AddBoat,
            DeleteBoat,
            ChangeBoat

        }
        // Skapar nytt enum
        MenuStatus status = MenuStatus.None;

        public ViewAll view;
        public Repository r;
        // gör meny för alla val
        public void doMenu()
        {
            // lista med alla personer
            IList<Person> myPersonList = r.getPersons();
            bool exit = false;
            while (!exit)
            {
                // en bool som kollar om det finns personer
                bool noPerson = myPersonList.Count == 0;
                // Laddar upp menyn direkt
                view.Menu();
                // Läser av vad personen matar in för val.
                string tempChoice = Console.ReadLine();
                // Kollar om valet är mellan 0-9
                if (IsNumberAndInLimit(tempChoice, 9))
                {
                    // gör om det till int istället
                    int choice = int.Parse(tempChoice);
                    // kollar om det finns personer eller om valet är 1 eller mindre
                    if (CheckPersons(myPersonList) || choice <= 1)
                    {
                        CheckStatus(choice); // Kollar vilket enum det blir för menyvalet
                        view.Clear(); // Rensar allt skräp från console
                        switch (status)
                        {
                            case MenuStatus.Exit: // Om det blir exit så lämnar vi while-loopen
                                exit = true;
                                break;
                            case MenuStatus.AddPerson:
                                // p ropar på addPerson som skapar person och retunerar det
                                Person p = AddPerson();
                                // Om p inte är tom
                                if (p != null)
                                {
                                    myPersonList.Add(p);
                                    r.Save(myPersonList); // sparar
                                }
                                ViewAll.ContinueOnKeyPressed();
                                break;

                            case MenuStatus.ViewPersons:

                                // Visar alla personer mindre detaljerat
                                view.Render(myPersonList);
                                ViewAll.ContinueOnKeyPressed();
                                break;

                            case MenuStatus.ViewPersonsInfo:
                                // Visar personer mer detaljerat
                                view.RenderSpecific(myPersonList);
                                ViewAll.ContinueOnKeyPressed();
                                break;

                            case MenuStatus.DeletePerson:
                                // Visar meddelande
                                view.RenderMessage("Ta Bort Medlem");
                                // går in i DeletePerson med mypersonlist och retunerar
                                myPersonList = DeletePerson(myPersonList);
                                r.Save(myPersonList); // Sparar
                                ViewAll.ContinueOnKeyPressed();
                                break;

                            case MenuStatus.ChangePerson:
                                // Visar meddelande
                                view.RenderMessage("Ändra Medlem");
                                // går in i ChangePerson och retunerar
                                myPersonList = ChangePerson(myPersonList);
                                r.Save(myPersonList); // Sparar
                                ViewAll.ContinueOnKeyPressed();
                                break;
                            case MenuStatus.ViewOnePerson:
                                // Visar meddelande
                                view.RenderMessage("Välj specifik Medlem");
                                // går in i SpecificMember och retunerar
                                myPersonList = SpecificMember(myPersonList);
                                r.Save(myPersonList); // sparar
                                ViewAll.ContinueOnKeyPressed();
                                break;
                            case MenuStatus.AddBoat:

                                // vad som ska visas
                                view.RenderMessage("Lägg Till Båt");
                                // går in i AddBoat som sedan retunerar resultatet
                                myPersonList = AddBoat(myPersonList); // retunerar resultatet

                                r.Save(myPersonList); // sparar
                                ViewAll.ContinueOnKeyPressed();
                                break;
                            case MenuStatus.DeleteBoat:

                                view.RenderMessage("Ta Bort Båt");
                                // Ropar på DeleteBoat och skickar med våra personer
                                // För att ta bort båt för en viss person
                                myPersonList = DeleteBoat(myPersonList);

                                if (myPersonList == null){view.RenderMessage("Fel inmatning");}
                                else { r.Save(myPersonList); }

                                ViewAll.ContinueOnKeyPressed();
                                break;
                            case MenuStatus.ChangeBoat:
                                // Om vi har det så visar vi personer man kan ändra båt på
                                // och sparar händelse
                                view.RenderMessage("Ändra Båt");
                                myPersonList = ChangeBoat(myPersonList);
                                if (myPersonList == null) { view.RenderMessage("Fel inmatning"); }
                                else { r.Save(myPersonList); }

                                ViewAll.ContinueOnKeyPressed();
                                break;
                        }
                    }
                    else
                    {
                        view.RenderMessage("Det finns inga personer");
                        ViewAll.ContinueOnKeyPressed();
                    }
                }
                else { view.RenderMessage("Fel inmatning"); }
            }
        }

        // AddPerson skapar ett person-objekt och retuneras
        public Person AddPerson()
        {
            Person p = view.addPerson();
            view.RenderMessage("Tillagd");
            return p;
        }
        // DeletePerson listar fram alla medlemmar i en fin lista
        // Man väljer vilken person i listan som ska bort sedan så sparas det i filen
        public IList<Person> DeletePerson(IList<Person> persons)
        {
            string tempNumber = "1";
            // Metoden körs ända tills den kmr till break
            while (true)
            {
                    ViewAll.RenderSelect(persons);
                    view.ShowNumber(0, persons.Count);
                    tempNumber = Console.ReadLine();

                    // Gjorde en metod som kollar om det är ett nummer och inte för stort eller för litet tal
                    if (IsNumberAndPersonLimit(tempNumber, persons))
                    {
                        if (int.Parse(tempNumber) == 0) { return persons; };

                        int number = int.Parse(tempNumber) - 1;
                        persons.Remove(persons[number]);

                        view.RenderMessage("Borttagen");
                        return persons;
                    }
                    else { view.RenderMessage("Fel inmatning"); }
            }
        }

        //ChangePerson är som DeletePerson
        // Bara de att man får ändra och lägga nya uppgifter i PersonList
        public IList<Person> ChangePerson(IList<Person> persons)
        {
            string tempNumber = "1";
            while (true)
            {
                try
                {
                    ViewAll.RenderSelect(persons);
                    view.ShowNumber(0, persons.Count);
                    tempNumber = Console.ReadLine();

                    // Gjorde en metod som kollar om det är ett nummer och inte för stort eller för litet tal
                    if (IsNumberAndPersonLimit(tempNumber, persons))
                    {
                        if (int.Parse(tempNumber) == 0) { return persons; }
                        
                        view.RenderMessage("Ändrad");
                        return view.ChangePersonRecords(persons, tempNumber);
                    }
                    else { view.RenderMessage("Fel inmatning"); }
                }
                catch
                {
                    throw new ArgumentException("Nu vart det nå galet fel.");
                }
            }
        
        }

        // SpecificMember gör att man väljer vilken person man ska använda
        // För att se detaljerat information på endast den personen
        public IList<Person> SpecificMember(IList<Person> persons)
        {
            string tempNumber = "1";
            // Allt körs inom denna while-loop tills det kmr till break
            while (true)
            {
                try
                {
                    ViewAll.RenderSelect(persons);
                    view.ShowNumber(0, persons.Count);
                    tempNumber = Console.ReadLine();


                    
                    // en metod som kollar om det är ett nummer och inte för stort eller för litet tal
                    if (IsNumberAndPersonLimit(tempNumber, persons))
                    {
                        if (int.Parse(tempNumber) == 0) { return persons; }
                        int number = int.Parse(tempNumber) - 1;
                        view.RenderPerson(persons[number]);
                        return persons;
                    }
                    else { view.RenderMessage("Fel inmatning"); }
                }
                catch { throw new ArgumentException("Nu vart det nå galet fel."); }
            }
        }
        public IList<Person> AddBoat(IList<Person> persons)
        {
            while (true )
            {
                try
                {
                    double trydouble;
                    string tempNumberOfPerson = "1"; // numberPerson blir automatiskt 1.
                    ViewAll.RenderSelect(persons);
                    // Om antalet personer är mer än 1 så måste man välja person själv.
                    view.ShowNumber(0, persons.Count);
                    // Väljer person
                    tempNumberOfPerson = Console.ReadLine();

                    // Kollar så att det är ett nummer och inom räckvid
                    if (IsNumberAndPersonLimit(tempNumberOfPerson, persons))
                    {
                        if (int.Parse(tempNumberOfPerson) == 0) { return persons; }
                        int NumberOfPerson = int.Parse(tempNumberOfPerson) - 1;
                        // Ange hur många båtar man vill lägga till
                       view.fixString("Ange hur många båtar du vill lägga till: ");
                        string numberBoats = Console.ReadLine();

                        // Kollar så att inmatningen är ett nr och inte 0 eller mindre
                        if (IsNumberAndInLimit(numberBoats, 50))
                        {
                            persons[NumberOfPerson].setNumberOf(int.Parse(numberBoats));
                            Boat[] boat = new Boat[int.Parse(numberBoats)];

                            string tempNum;
                            for (int i = 0; i < int.Parse(numberBoats); i++)
                            {
                                // Lägger in Typ och längd på båten
                                view.BoatTypes();
                                string Type = null;
                                tempNum = Console.ReadLine();

                                // Kollar så tempNum är ett nr och är inom 1-5
                                if (IsNumberAndInLimit(tempNum, 5))
                                {
                                    // Sen sätter vi num är tempNum
                                    int num = int.Parse(tempNum);

                                    // Sedan sätter vi Type beroende på vad num är
                                    switch (num)
                                    {
                                        case 1:
                                            Type = "Segelbåt";
                                            break;
                                        case 2:
                                            Type = "Motorseglare";
                                            break;
                                        case 3:
                                            Type = "Motorbåt";
                                            break;
                                        case 4:
                                            Type = "Kajak/Kanot";
                                            break;
                                        case 5:
                                            Type = "Övrigt";
                                            break;

                                        default:
                                            Type = "Övrigt";
                                            break;
                                    }
                                    // Sätter längden på båten
                                    view.fixString("Vad är längden?(meter): ");
                                    string Length = Console.ReadLine();

                                    // Kollar så att längden är ett nr
                                    if (!double.TryParse(Length, out trydouble) && double.Parse(Length) <= 0) { view.RenderMessage("Fel inmatning"); }
                                    else
                                    {
                                        boat[i] = new Boat(Type, double.Parse(Length));
                                        persons[NumberOfPerson].setNumberOf(persons[NumberOfPerson].getAntal() + 1);
                                        persons[NumberOfPerson].setBoat(boat[i]);

                                        // Sätter antalet båtar på personen
                                        persons[NumberOfPerson].setNumberOf(boat.Length);
                                        // Sparar båten
                                        view.RenderMessage("Tillagd");
                                        return persons;
                                    }
                                }
                                else { view.RenderMessage("Fel inmatning"); }
                            }
                        }
                        else { view.RenderMessage("Fel inmatning"); }
                    }
                    else { view.RenderMessage("Fel inmatning"); }
                }
                catch
                { throw new ArgumentException("Nu vart de nå knasigt när vi försökte skapa båtar"); }
            }
        }
        public IList<Person> DeleteBoat(IList<Person> persons)
        {
            while (true)
            {
                try
                {
                    string tempNumberOfPerson = "1";
                    string tempNumberOfBoat = "1";

                    ViewAll.RenderSelect(persons); // Visar personer i en lista
                    view.ShowNumber(0, persons.Count);
                    tempNumberOfPerson = Console.ReadLine(); // Läser in vad man matar in

                    // Om nummret stämmer och inte är mindre än 0 och större än antalet personer
                    if (IsNumberAndPersonLimit(tempNumberOfPerson, persons))
                    {
                        if (int.Parse(tempNumberOfPerson) == 0) { return persons; }
                        int NumberOfPerson = int.Parse(tempNumberOfPerson) - 1;

                        // Skapar en ny list med båtobjekt, av den personen vi valde
                        List<Boat> boats = persons[NumberOfPerson].getBoat();

                        // Om personen har mer än 0 båtar att hateras med
                        if (boats.Count > 0)
                        {
                            // Så får vi välja vilken båt som ska tas bort
                            view.RenderBoat(persons[NumberOfPerson]);

                            view.ShowNumber(1, boats.Count);
                            tempNumberOfBoat = Console.ReadLine();
                            // Kollar så valet är ett tal och att det är högre än 0 och lika eller mindre än antalet båtar
                            if (IsNumberAndBoatLimit(tempNumberOfBoat, boats))
                            {
                                // Skapar ny variabel som blir samma som man mata in fast -1
                                int NumberOfBoat = int.Parse(tempNumberOfBoat) - 1;
                                // Tar bort den båten i listan. 
                                boats.Remove(boats[NumberOfBoat]);

                                // bekräftar och retunerar
                                view.RenderMessage("Borttagen");
                                return persons;
                            }
                            // Detta skrivs ut om valet man skrev om båtar
                            // Är felaktigt
                            else
                            { view.RenderMessage("Fel inmatning"); }
                        }
                        else
                        { view.RenderMessage("Finns inga båtar att hanteras med, välj någon annan person"); } // Detta skrivs ut om det inte finns några båtar att välja mellan
                    }
                    // Detta skrivs om val av personer är felaktigt
                    else
                    { view.RenderMessage("Fel inmatning"); }
                }
                catch
                { throw new ArgumentException("Nu blev de nå fel här"); }
            }
        }
        // Byter info på båt
        public IList<Person> ChangeBoat(IList<Person> persons)
        {
            // så länge det är true
            while (true)
            {
                // så ska metoden förska med
                try
                {
                    string Type;
                    string Length;
                    string tempNum;
                    string tempNumberOfPerson = "1";
                    string tempNumberOfBoat = "1";

                    ViewAll.RenderSelect(persons);

                    view.ShowNumber(0, persons.Count);

                    tempNumberOfPerson = Console.ReadLine(); // Läser in vad man matar in
                    if (IsNumberAndPersonLimit(tempNumberOfPerson, persons))
                    {
                        if (int.Parse(tempNumberOfPerson) == 0) // Så om man väljer 0 så går man tillbaka till menyn
                        {
                            return persons;
                        }
                        // Om nummret stämmer och inte är mindre än 0 och större än antalet personer
                        if (IsNumberAndPersonLimit(tempNumberOfPerson, persons))
                        {
                            int NumberOfPerson = int.Parse(tempNumberOfPerson) - 1;

                            List<Boat> boats = persons[NumberOfPerson].getBoat();   // Skapar en ny list med båtobjekt, av den personen vi valde

                            // Om personen har mer än 0 båtar att hateras med
                            if (boats.Count > 0)
                            {
                                view.RenderBoat(persons[NumberOfPerson]);
                                view.ShowNumber(1, persons.Count);  // Så får vi välja vilken båt som ska tas bort
                                tempNumberOfBoat = Console.ReadLine();   

                                // Kollar så valet är ett tal och att det är högre än 0 och lika eller mindre än antalet båtar
                                if (IsNumberAndBoatLimit(tempNumberOfBoat, boats))
                                {
                                    int NumberOfBoat = int.Parse(tempNumberOfBoat) - 1;

                                    view.BoatTypes();
                                    tempNum = Console.ReadLine();
                                    // Kollar så tempNum är ett nr och är inom 1-5
                                    if (IsNumberAndInLimit(tempNum, 5))
                                    {
                                        int num = int.Parse(tempNum);
                                        // Sedan sätter vi Type beroende på vad num är
                                        switch (num)
                                        {
                                            case 1:
                                                Type = "Segelbåt";
                                                break;
                                            case 2:
                                                Type = "Motorseglare";
                                                break;
                                            case 3:
                                                Type = "Motorbåt";
                                                break;
                                            case 4:
                                                Type = "Kajak/Kanot";
                                                break;
                                            case 5:
                                                Type = "Övrigt";
                                                break;

                                            default:
                                                Type = "Övrigt";
                                                break;
                                        }

                                        boats[NumberOfBoat].setType(Type);
                                        view.fixString("Ange BåtLängd(meter): ");
                                        Length = Console.ReadLine();

                                        if (IsNumberAndInLimit(Length, 9999999))
                                        {
                                            boats[NumberOfBoat].setLength(double.Parse(Length));
                                        }
                                        else { view.RenderMessage("Fel inmatning"); }
                                        
                                        view.RenderMessage("Ändrad");
                                        return persons;
                                    }
                                    else
                                    { view.RenderMessage("Fel inmatning"); }
                                }
                                else
                                { view.RenderMessage("Fel inmatning"); }
                            }
                            else
                            { view.RenderMessage("Finns inga båtar att hanteras med, välj någon annan person"); }
                            
                        }
                        // Detta skrivs om val av personer är felaktigt
                        else
                        { view.RenderMessage("Fel inmatning"); }
                        
                    }
                    else { view.RenderMessage("Fel inmatning"); }
                }
                catch { throw new ArgumentException("Nu blev de nå fel här"); }
            }
        }
        // Kollar om det är 0-Person.count
        public static bool IsNumberAndPersonLimit(string number, IList<Person> person)
        {
            int index;
            if (!int.TryParse(number, out index) &&
                index == 0 || int.Parse(number) > person.Count ||
                (int.Parse(number) < 0)) { return false; }
            
            return true;
        }
        // Kollar om valet är 0-Boat.count
        public static bool IsNumberAndBoatLimit(string number, List<Boat> boat)
        {
            int index;
            if (!int.TryParse(number, out index) &&
                index == 0 || int.Parse(number) > boat.Count ||
                (int.Parse(number) <= 0)) { return false; }
            
            return true;
        }
        // Kollar om numret är 0 till de man själv matar in
        public static bool IsNumberAndInLimit(string number, int count)
        {
            int index;
            if (!int.TryParse(number, out index) &&
                index == 0 || int.Parse(number) > count ||
                (int.Parse(number) < 0)) { return false; }
            return true;
        }
        // Kollar om de finns personer
        public static bool CheckPersons(IList<Person> persons)
        {
            if (persons.Count == 0) { return false; }
            return true;
        }
        // Kollar statusen för menyvalen
        public void CheckStatus(int choice)
        {
            switch (choice)
            {
                case 0:
                    status = MenuStatus.Exit;
                    break;
                case 1:
                    status = MenuStatus.AddPerson;
                    break;
                case 2:
                    status = MenuStatus.ViewPersons;
                    break;
                case 3:
                    status = MenuStatus.ViewPersonsInfo;
                    break;
                case 4:
                    status = MenuStatus.DeletePerson;
                    break;
                case 5:
                    status = MenuStatus.ChangePerson;
                    break;
                case 6:
                    status = MenuStatus.ViewOnePerson;
                    break;
                case 7:
                    status = MenuStatus.AddBoat;
                    break;
                case 8:
                    status = MenuStatus.DeleteBoat;
                    break;
                case 9:
                    status = MenuStatus.ChangeBoat;
                    break;
                default:
                    status = MenuStatus.Exit;
                    break;
            }
        }
    }
}
